home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 38 / Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso / -seriously_amiga- / programming / other / cyberxxxsrc / cyberavi / txt / cyberavisync.mod < prev    next >
Text File  |  1999-02-08  |  9KB  |  287 lines

  1. MODULE CyberAVISync;
  2.  
  3. (* $IFNOT DEBUG *)
  4.   (* $StackChk- $OvflChk- $RangeChk- $CaseChk- $ReturnChk- $NilChk- $TypeChk- $OddChk- $ClearVars- *)
  5. (* $END *)
  6.  
  7. (* /// ------------------------------- "IMPORT" -------------------------------- *)
  8. IMPORT  cu:=CyberAVIUtils,
  9.         d:=Dos,
  10.         e:=Exec,
  11.         g:=CyberAVIGlobals,
  12.         m:=MathFFP,
  13.         mu:=MathUtils,
  14.         t:=Timer,
  15.         y:=SYSTEM;
  16. (* \\\ ------------------------------------------------------------------------- *)
  17.  
  18. (* /// --------------------------------- "VAR" --------------------------------- *)
  19. VAR     timerPort: e.MsgPortPtr;
  20.         timerOpen: BOOLEAN;
  21.         timerSig - : LONGINT;
  22.         timerIO: t.TimeRequestPtr;
  23.         nextTime: t.EClockVal;
  24.         frameTime: t.EClockVal;
  25.         syncTime: t.EClockVal;
  26.         oneSecond: t.EClockVal;
  27.         microsPerEClock: REAL;
  28.         start: t.EClockVal;
  29.         stop: t.EClockVal;
  30.         speedChanged - : BOOLEAN;
  31. (* \\\ ------------------------------------------------------------------------- *)
  32.  
  33. (* /// --------------------- "PROCEDURE Micros2EClocks()" ---------------------- *)
  34. PROCEDURE Micros2EClocks(micros: LONGINT): LONGINT;
  35. BEGIN
  36.   RETURN mu.floor(micros/microsPerEClock);
  37. END Micros2EClocks;
  38. (* \\\ ------------------------------------------------------------------------- *)
  39.  
  40. (* /// ------------------------- "PROCEDURE GetFPS()" -------------------------- *)
  41. PROCEDURE GetFPS * (): LONGINT;
  42. BEGIN
  43.   RETURN mu.floor(1000000/g.animInfo.avih.microsPerFrame);
  44. END GetFPS;
  45. (* \\\ ------------------------------------------------------------------------- *)
  46.  
  47. (* /// --------------------- "PROCEDURE GetPlayingTime()" ---------------------- *)
  48. PROCEDURE GetPlayingTime * (): REAL;
  49. BEGIN
  50.   IF (g.animInfo.vids.strh.scale>0) & (g.animInfo.vids.strh.rate>0) THEN
  51.     RETURN (g.animInfo.vids.strh.scale*g.animInfo.avih.totalFrames)/g.animInfo.vids.strh.rate;
  52.   ELSE
  53.     RETURN (g.animInfo.avih.totalFrames*g.animInfo.avih.microsPerFrame)/1000000;
  54.   END;
  55. END GetPlayingTime;
  56. (* \\\ ------------------------------------------------------------------------- *)
  57.  
  58. (* /// ------------------------- "PROCEDURE DoStats()" ------------------------- *)
  59. PROCEDURE DoStats * (framesDone: LONGINT;
  60.                      framesSkipped: LONGINT);
  61.  
  62. VAR     fps: REAL;
  63.         time: REAL;
  64.         realFPS: e.STRING;
  65.         realTime: e.STRING;
  66.         expFPS: e.STRING;
  67.         expTime: e.STRING;
  68.         diff: REAL;
  69.         diffS: e.STRING;
  70.         total: LONGINT;
  71.  
  72. BEGIN
  73.   mu.Sub64(stop,start);
  74.  
  75.   total:=mu.min(g.animInfo.avih.totalFrames,g.animInfo.vids.strh.length);
  76.   time:=((stop.hi*4294967296.0+stop.lo)*microsPerEClock)/1000000;
  77.   fps:=framesDone/time;
  78.   diff:=time;
  79.   mu.real2str(time,realTime,6);
  80.   mu.real2str(fps,realFPS,2);
  81.  
  82.   time:=GetPlayingTime();
  83.   fps:=total/time;
  84.   mu.real2str(time,expTime,6);
  85.   mu.real2str(fps,expFPS,2);
  86.  
  87.   mu.real2str(diff-time,diffS,6);
  88.  
  89.   d.PrintF("\n"
  90.            "Statistics:\n"
  91.            "  total frames    : %4ld\n"
  92.            "  frames processed: %4ld\n"
  93.            "  frames displayed: %4ld\n"
  94.            "  frames skipped  : %4ld\n"
  95.            "  real time used  : %11s seconds (%6s fps)\n"
  96.            "  expected time   : %11s seconds (%6s fps)\n"
  97.            "  difference      : %11s seconds\n"
  98.            "\n",total,
  99.                 framesDone,
  100.                 framesDone-framesSkipped,
  101.                 framesSkipped,
  102.                 y.ADR(realTime),y.ADR(realFPS),
  103.                 y.ADR(expTime),y.ADR(expFPS),
  104.                 y.ADR(diffS));
  105. END DoStats;
  106. (* \\\ ------------------------------------------------------------------------- *)
  107.  
  108. (* /// ----------------------- "PROCEDURE CloseTimer()" ------------------------ *)
  109. PROCEDURE CloseTimer();
  110. BEGIN
  111.   IF timerOpen THEN
  112.     IF e.CheckIO(timerIO)=NIL THEN (* es läuft noch ein Request *)
  113.       e.AbortIO(timerIO);
  114.       y.SETREG(0,e.WaitIO(timerIO));
  115.     END;
  116.     e.CloseDevice(timerIO);
  117.   END;
  118.   IF timerIO#NIL THEN e.DeleteIORequest(timerIO); END;
  119.   IF timerPort#NIL THEN e.DeleteMsgPort(timerPort); END;
  120. END CloseTimer;
  121. (* \\\ ------------------------------------------------------------------------- *)
  122.  
  123. (* /// ------------------------ "PROCEDURE OpenTimer()" ------------------------ *)
  124. PROCEDURE OpenTimer(): BOOLEAN;
  125.  
  126. VAR     now: t.EClockVal;
  127.  
  128. BEGIN
  129.   timerOpen:=FALSE;
  130.   timerIO:=NIL;
  131.   timerPort:=e.CreateMsgPort();
  132.   IF timerPort=NIL THEN
  133.     d.PrintF("Can't create timer message port\n");
  134.     RETURN FALSE;
  135.   END;
  136.   timerSig:=timerPort.sigBit;
  137.   timerIO:=e.CreateIORequest(timerPort,SIZE(timerIO^));
  138.   IF timerIO=NIL THEN
  139.     d.PrintF("Can't create timer iorequest\n");
  140.     RETURN FALSE;
  141.   END;
  142.   timerOpen:=(e.OpenDevice(t.timerName,t.waitEClock,timerIO,LONGSET{})=0);
  143.   IF ~timerOpen THEN
  144.     d.PrintF("Can't open timer.device\n");
  145.     RETURN FALSE;
  146.   END;
  147.   timerIO.node.command:=t.addRequest;
  148.   t.base:=timerIO.node.device;
  149.   microsPerEClock:=1000000.0/t.ReadEClock(now);
  150.   oneSecond.hi:=0;
  151.   oneSecond.lo:=Micros2EClocks(1000000);
  152.   RETURN TRUE;
  153. END OpenTimer;
  154. (* \\\ ------------------------------------------------------------------------- *)
  155.  
  156. (* /// -------------------------- "PROCEDURE Wait()" --------------------------- *)
  157. PROCEDURE Wait * (secs: LONGINT);
  158.  
  159. VAR     now: t.EClockVal;
  160.         until: t.EClockVal;
  161.  
  162. BEGIN
  163.   until.hi:=0;
  164.   until.lo:=Micros2EClocks(secs*1000000);
  165.   y.SETREG(0,t.ReadEClock(now));
  166.   mu.Add64(until,now);
  167.   timerIO.time:=y.VAL(t.TimeVal,until);
  168.   y.SETREG(0,e.DoIO(timerIO));
  169. END Wait;
  170. (* \\\ ------------------------------------------------------------------------- *)
  171.  
  172. (* /// ----------------------- "PROCEDURE StartTimer()" ------------------------ *)
  173. PROCEDURE StartTimer * ();
  174. BEGIN
  175.   y.SETREG(0,t.ReadEClock(start));
  176.   nextTime:=start;
  177.   syncTime:=start;
  178.   mu.Add64(syncTime,oneSecond);
  179.   timerIO.time:=y.VAL(t.TimeVal,nextTime);
  180.   e.SendIO(timerIO);
  181. END StartTimer;
  182. (* \\\ ------------------------------------------------------------------------- *)
  183.  
  184. (* /// ------------------------ "PROCEDURE StopTimer()" ------------------------ *)
  185. PROCEDURE StopTimer();
  186. BEGIN
  187.   y.SETREG(0,t.ReadEClock(stop));
  188. END StopTimer;
  189. (* \\\ ------------------------------------------------------------------------- *)
  190.  
  191. (* /// ----------------------- "PROCEDURE PauseTimer()" ------------------------ *)
  192. PROCEDURE PauseTimer * (pause: BOOLEAN);
  193.  
  194. VAR     temp: t.EClockVal;
  195.         now: t.EClockVal;
  196.  
  197. BEGIN
  198.   IF pause THEN
  199.     temp:=nextTime;
  200.     y.SETREG(0,t.ReadEClock(now));
  201.     mu.Sub64(temp,now);
  202.     frameTime:=temp;
  203.     nextTime:=now;
  204.   ELSE
  205.     y.SETREG(0,t.ReadEClock(nextTime));
  206.     mu.Add64(nextTime,frameTime);
  207.     syncTime:=nextTime;
  208.     frameTime.hi:=0;
  209.     frameTime.lo:=Micros2EClocks(g.animInfo.avih.microsPerFrame);
  210.     IF g.animInfo.avih.totalFrames#g.animInfo.vids.strh.length THEN
  211.       frameTime.lo:=Micros2EClocks(g.animInfo.avih.microsPerFrame*g.animInfo.avih.totalFrames);
  212.     END;
  213.     e.SendIO(timerIO);
  214.   END;
  215. END PauseTimer;
  216. (* \\\ ------------------------------------------------------------------------- *)
  217.  
  218. (* /// ---------------------- "PROCEDURE SetFrameDelay()" ---------------------- *)
  219. PROCEDURE SetFrameDelay * (delay: LONGINT);
  220. BEGIN
  221.   IF e.CheckIO(timerIO)=NIL THEN
  222.     e.AbortIO(timerIO);
  223.     y.SETREG(0,e.WaitIO(timerIO));
  224.   END;
  225.   y.SETREG(0,t.ReadEClock(nextTime));
  226.   IF delay=-1 THEN
  227.     frameTime.hi:=0;
  228.     frameTime.lo:=Micros2EClocks(g.animInfo.avih.microsPerFrame);
  229.     IF g.animInfo.avih.totalFrames>g.animInfo.vids.strh.length THEN
  230.       frameTime.lo:=Micros2EClocks(g.animInfo.avih.microsPerFrame*g.animInfo.avih.totalFrames);
  231.     END;
  232.     speedChanged:=FALSE;
  233.   ELSE
  234.     frameTime.hi:=0;
  235.     frameTime.lo:=Micros2EClocks(delay);
  236.     speedChanged:=TRUE;
  237.   END;
  238. END SetFrameDelay;
  239. (* \\\ ------------------------------------------------------------------------- *)
  240.  
  241. (* /// ---------------------- "PROCEDURE DoFrameDelay()" ----------------------- *)
  242. PROCEDURE DoFrameDelay * (skipping: BOOLEAN);
  243. BEGIN
  244.   mu.Add64(nextTime,frameTime);
  245.   IF ~skipping THEN timerIO.time:=y.VAL(t.TimeVal,nextTime); END;
  246.   e.SendIO(timerIO); (* falls nicht warten, dann einfach den Request noch mal mit der alten Zeit starten *)
  247. END DoFrameDelay;
  248. (* \\\ ------------------------------------------------------------------------- *)
  249.  
  250. (* /// ------------------------- "PROCEDURE IsSync()" -------------------------- *)
  251. PROCEDURE IsSync * (): BOOLEAN;
  252.  
  253. VAR     now: t.EClockVal;
  254.         ret: BOOLEAN;
  255.  
  256. BEGIN
  257.   IF speedChanged THEN
  258.     ret:=TRUE; (* falls Geschwindigkeit geändert, dann immer synchron *)
  259.   ELSE
  260.     y.SETREG(0,t.ReadEClock(now));
  261.     mu.Sub64(now,frameTime); (* synctime>=now-frametime? *)
  262.     ret:=(mu.Cmp64(syncTime,now)<=0); (* syncTime ist noch später als now => synchron *)
  263.   END;
  264.   IF mu.Cmp64(syncTime,nextTime)>=0 THEN mu.Add64(syncTime,oneSecond); END; (* eine Sekunde ist vorbei, syncTime aktualisieren *)
  265.   RETURN ret;
  266. END IsSync;
  267. (* \\\ ------------------------------------------------------------------------- *)
  268.  
  269. (* /// --------------------- "PROCEDURE Wait4LastFrame()" ---------------------- *)
  270. PROCEDURE Wait4LastFrame * ();
  271. BEGIN
  272.   IF e.CheckIO(timerIO)=NIL THEN
  273.     y.SETREG(0,e.Wait(LONGSET{timerSig})); (* auf Timer warten, sonst wird der letzte Frame zu kurz dargestellt *)
  274.   END;
  275.   StopTimer();
  276. END Wait4LastFrame;
  277. (* \\\ ------------------------------------------------------------------------- *)
  278.  
  279. BEGIN
  280.   IF ~OpenTimer() THEN
  281.     d.PrintF("Can't open timer\n");
  282.     HALT(0);
  283.   END;
  284. CLOSE
  285.   CloseTimer();
  286. END CyberAVISync.
  287.